use sqlx::{PgPool, Error};
use struct_field_names_as_array::FieldNamesAsSlice;

use crate::core::psqlx_tools::SqlString;
use crate::model::taxon::TaxonModel;
use crate::model::model::Model;
use crate::types::backend::taxon_type::{TaxonForm, TaxonRow};
use crate::types::common::OptionRow;


pub struct TaxonService;

impl TaxonService {
    /// 获取分类分页列表
    /// 正确返回 TaxonList 数据，数据包括页码，每页数量，当前页TaxonRow数据数组，总条数
    /// 错误返回 sqlx::Error
    pub async fn get_taxons(db: &PgPool) -> Result<Vec<TaxonRow>, Error> {
        let model = TaxonModel::new();
        
        let sql = SqlString::new(model.table())
        .field_slice(TaxonRow::FIELD_NAMES_AS_SLICE)
        .order_primary_key_desc()
        .select();

        let res = sqlx::query_as::<_, TaxonRow>(&sql)
        .fetch_all(db)
        .await;
        
        res
        
    }

    /// 获取分类详情
    /// 参数 id 分类id
    /// 正确返回 TaxonForm 表单数据
    /// 错误返回 sqlx::Error
    pub async fn get_taxon_by_id(db: &PgPool, id: i64) -> Result<TaxonForm, Error> {
        let model = TaxonModel::new();
        let sql: String = SqlString::new(model.table())
        .field_slice(TaxonForm::FIELD_NAMES_AS_SLICE)
        .append_primary_key()
        .where_primary_key()
        .select();

        let res = sqlx::query_as::<_, TaxonForm>(&sql)
        .bind(id)
        .fetch_one(db)
        .await;
        res
    }

    /// 添加分类
    /// 参数 data TaxonForm 表单数据
    /// 正确返回 bool true
    /// 错误返回 sqlx::Error
    pub async fn insert_taxon(db: &PgPool, data: &TaxonForm) -> Result<bool, Error> {
        let model = TaxonModel::new();
        let sql = SqlString::new(model.table())
        .field_slice(TaxonForm::FIELD_NAMES_AS_SLICE)
        .insert();

        let res = sqlx::query(&sql)
        .bind(&data.name)
        .bind(&data.image)
        .bind(&data.order_by)
        .execute(db)
        .await;

        match res {
            Ok(data) => Ok(data.rows_affected() > 0),
            Err(e) => Err(e)
        }
    }

    /// 更新分类
    /// 参数 data TaxonForm 表单数据
    /// 正确返回 bool true
    /// 错误返回 sqlx::Error
    pub async fn update_taxon(db: &PgPool, id:i64, data: &TaxonForm) -> Result<bool, Error> {
        let model = TaxonModel::new();
        let sql = SqlString::new(model.table())
        .field_slice(TaxonForm::FIELD_NAMES_AS_SLICE)
        .where_primary_key()
        .update();

        let res = sqlx::query(&sql)
        .bind(id)
        .bind(&data.name)
        .bind(&data.image)
        .bind(&data.order_by)
        .execute(db)
        .await;

        match res {
            Ok(data) => Ok(data.rows_affected() > 0),
            Err(e) => Err(e)
        }
    }

    /// 删除分类
    /// 参数 id 分类id
    /// 正确返回 bool true
    /// 错误返回 sqlx::Error
    pub async fn delete_taxon(db: &PgPool, id: i64) -> Result<bool, Error> {
        let model = TaxonModel::new();
        let sql = SqlString::new(model.table())
        .where_primary_key()
        .delete();

        let res = sqlx::query(&sql)
        .bind(id)
        .execute(db)
        .await;

        match res {
            Ok(data) => Ok(data.rows_affected() > 0),
            Err(e) => Err(e)
        }
    }

    /// 分类是否存在
    /// 参数 id 区域id
    /// 正确返回 数量
    /// 错误返回 sqlx::Error
    pub async fn exist_taxon_by_id(db: &PgPool, id: i64) -> Result<i64, Error> {
        let model = TaxonModel::new();
        let sql = SqlString::new(model.table())
        .where_primary_key()
        .count();

        let res = sqlx::query_scalar::<_, i64>(&sql)
        .bind(id)
        .fetch_one(db)
        .await;

        res
    }

    /// 获取分类下拉
    /// 正确返回 OptionRow 数组
    /// 错误返回 sqlx::Error
    pub async fn get_option_taxons(db: &PgPool) -> Result<Vec<OptionRow>, Error> {
        let model = TaxonModel::new();
        let sql = SqlString::new(model.table())
        .field_slice(OptionRow::FIELD_NAMES_AS_SLICE)
        .select();
    
        let res = sqlx::query_as::<_, OptionRow>(&sql)
        .fetch_all(db)
        .await;
       
        res
    }
}
    